<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    
</body>
</html>
<script>
    // 与Iterator接口的关系
    // 任意一个对象的遍历器生成函数 Symbol.iterator 方法 等于该对象的遍历器生成函数 调用该函数 会返回该对象的一个遍历器对象
    // 由于Generator函数就是遍历器生成函数 因此可以把Generator赋值给对象的Symbol.iterator属性 
    // 使得该对象具有Iterator接口

    var myIterable = {};
    myIterable[Symbol.iterator] = function* () {
        yield 1;
        yield 2;
        yield 3;
    };

    [...myIterable] // [1, 2, 3]

    // 上面代码中 Generator函数赋值给Symbol.Iterator属性 从而使得myIterable对象具有Iterator接口
    // 可以被...运算符遍历了


    // Generator函数执行后 返回一个遍历器对象 该对象本身具有Symbol.iterator属性执行后返回自身
    function* gen(){
        // some code
    }

    var g = gen();

    g[Symbol.iterator]() === g
    // true

    // 上面代码中 gen是一个Generator函数 调用它会生成一个遍历器对象g
    // 它的 Symbol.Iterator 属性 也就是遍历器对象生成函数 执行后返回它自己


    // next方法的参数
    // yield表达式本身没有返回值 或者说总是返回undefined 
    // next方法可以带一个参数 该参数就会被当作上一个yield表达式的返回值
    function* f() {
        for(var i = 0; true; i++) {
            var reset = yield i;
            if(reset) { i = -1; }
        }
    }

    var g = f();

    g.next() // { value: 0, done: false }
    g.next() // { value: 1, done: false }
    g.next(true) // { value: 0, done: false }


    


</script>